<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        const bucket = new WeakMap();
        let activeEffect;
        const effectStack = []; //新增
        //原始数据
        const data = {
                text: "hello word",
                text2: "hello2",
                foo: 1
            }
            //设置里面的函数抽象到’追踪‘
        function track(target, key) {
            if (!activeEffect) {
                return;
            }
            let depsMap = bucket.get(target);
            if (!depsMap) {
                //用对象来做key
                bucket.set(target, (depsMap = new Map()))
            }
            let deps = depsMap.get(key);
            if (!deps) {
                depsMap.set(key, (deps = new Set()));
            }
            deps.add(activeEffect);
        }
        //设置的代码，抽象到这里
        function trigger(target, key) {

            const depsMap = bucket.get(target);
            if (!depsMap) {
                return;
            }
            const effects = depsMap.get(key);
            // effects && effects.forEach(fn => fn());
            //新增
            const effectToRun = new Set();
            effects && effects.forEach(fn => {
                if (fn !== activeEffect) {
                    effectToRun.add(fn);
                }
            });
            effectToRun.forEach(fn => fn())

        }
        const obj = new Proxy(data, {
            get(target, key) {
                track(target, key);
                return target[key]; //返回对应的值
            },
            set(target, key, newVal) {
                target[key] = newVal;
                trigger(target, key);
            }
        })

        //用于注册副作用函数
        function effect(fn) {
            const effectFn = () => {
                activeEffect = fn;
                //添加到数组最后
                effectStack.push(effectFn); //函数把自己放到数组里面
                fn();
                //
                effectStack.pop(); //移除掉数组最后一个
                activeEffect = effectStack[effectStack.length - 1];
            }
            effectFn();

        }
        let tmp1, tmp2;
        effect(() => {
            console.log("死循环？？")
            obj.foo += 1;
            document.body.innerText = obj.foo;
        });
    </script>
</body>

</html>